(function() {

    var
    $u = juliet.using({
        func : 'juliet.core.func-0.1',
        string : 'juliet.core.string-0.1',
        CustomInputWithPopupList : 'juliet.ui.input.withPopupList.CustomInputWithPopupList-0.1'
    }),
    $ = juliet.jQuery;

    var INNER_UI_ELEMENTS_TEMPLATE =
        '<span class="drop-down-select-title">${defaultValueTitle}</span>' +
        '<div class="drop-down-select-arrow"></div>' +
        '<input type="hidden" value="" />';

    var CustomInputWithPopupList = $u('CustomInputWithPopupList');

    var DropDownSelectClass = function() {

        // -------------------------------------------------------
        // -                        LOGIC                        -
        // -------------------------------------------------------

        /**
         * @param {Object} item Selected item. Object with "title" and "value" fields.
         * @private
         */
        this._dropDownSelectOnItemSelectedHandler = function(item) {
            this._controlElement.find('.drop-down-select-title').html(item.title);
            this._popupList.hide();

            var input = this._controlElement.find('input');
            input.val(item.value);
            input.trigger('blur'); // Force validation handler.
        };

        /**
         * @param {Object} item Selected item. Object with "title" and "value" fields.
         * @private
         */
        this._popupListOnItemSelectedHandler = function(item) {
            this.setSelectedItem(item);
        };

        /**
         * @private
         */
        this._subscribeOnEvents = function() {
            this._popupList.getObserver().subscribe('item-selected', this._popupListOnItemSelectedHandler, this);
            this._observer.subscribe('item-selected', this._dropDownSelectOnItemSelectedHandler, this);
        };

        /**
         * @private
         */
        this._createInnerUiElements = function() {
            this._controlElement.append($u('string').format(INNER_UI_ELEMENTS_TEMPLATE, {
                defaultValueTitle : 'не выбрано'
            }));
        };

        //
        // UI EVENTS HANDLERS
        //

        /**
         * @private
         */
        this._controlElementOnClickHandler = function() {
            if (!this._popupList.isVisible() && this._active) this._popupList.delayedShow();
        };

        /**
         * @private
         */
        this._bindEventsHandlers = function() {
            $u('func').bind(this._controlElement, 'click', this._controlElementOnClickHandler, this);
        };

        //
        // API
        //

        /**
         * @param {Object} value
         * @param {String} valuePropertyName
         */
        this.getItemByValue = function(value, valuePropertyName) {
            var data = this._popupList.getData(), i;

            for (i = 0; i < data.length; ++i) {
                if (data[i][valuePropertyName] == value) return data[i];
            }

            return null;
        };

        /**
         * @param o {Object} See "PopupListClass.setData" method for more details.
         */
        this.setData = function(o) {
            this._popupList.setData(o);
        };

        /**
         * Initialize instance with specified options.
         *
         * @param {Object} o Instance options. Contains:
         *     - {String} selector
         */
        this.initialize = function(o) {
            // Call parent's initialize function.
            DropDownSelectClass.prototype.initialize.call(this, o);

            this._createInnerUiElements();
            this._bindEventsHandlers();
            this._subscribeOnEvents();
        };

    };

    DropDownSelectClass.prototype = new CustomInputWithPopupList();

    juliet.registerModule('juliet.ui.input.withPopupList', 'DropDownSelect-0.1', DropDownSelectClass);

})();
